<?php
////////////////////////////////////////////////////////////////////////////////
//	  This file is part of PushLMS.
//
//    PushLMS is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    PushLMS is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with PushLMS.  If not, see <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////////////

/**
 * Users Controller
 *
 * Provides user CRUD and login methods for administration
 *
 * Licensed under GPL License
 * @link http://www.gnu.org/licenses/gpl.html
 *   
 * @package    PushLMS   
 * @subpackage UsersController
 * @since      2010
 * @license    GPL v3
 */

/**
 * Users Controller
 *
 * Controller for user CRUD and login methods 
 *
 * @package       pushLMS
 * @subpackage    pushLMS.UsersController
 */

class UsersController extends AppController {

/**
 * Enable admin scaffolding
 * Set to admin to allow scaffolding for general
 *
 * @var string
 * @access public
 */

	var $scaffold = 'admin';

/**
 * Array of helpers used in the views for the UsersController
 * Form, Javascript, JsValidate.Validation, Ajax, Captcha
 *
 * @var array
 * @access public
 */

	var $helpers = array('Form', 'Javascript', 'JsValidate.Validation', 'Ajax', 'Captcha');

/**
 * Array of models used in the UsersController
 * User, Course, Usergroup
 *
 * @var array
 * @access public
 */

	var $uses = array('User', 'Usergroup', 'Course');

/**
 * Array of pagination options for the listing of users
 * User, Course, Usergroup
 *
 * @var array
 * @access public
 */

	var $paginate = array(
		'limit' => 10,
		'order' => array(
			'User.id' => 'asc'
		)
	);

/**
 * beforeFilter() for UsersController
 * 
 * Standard beforeFilter() callback function for cakePHP controllers
 * @link http://book.cakephp.org/view/984/Callbacks
 * 
 * An Auth Allow list has been created for this beforeFilter()
 * 
 * captcha - to enable the captcha image for the signup process to work
 * login - allowing access to a HTML admin login form
 * register - allowing access to a HTML registration form for admin access
 * student_login - providing an openID login process (incomplete)
 * password_recover - providing a password recovery system for the admin
 * 
 * 
 */

	function beforeFilter() {

		$this->Auth->allow('captcha');	
		$this->Auth->allow('login');
		$this->Auth->allow('register');
		$this->Auth->allow('student_login');
		$this->Auth->allow('password_recover');

		$this->Auth->fields = array('username' => 'username', 'password' => 'password');
		$this->Auth->userScope = array('User.active' => true);
		$this->Auth->loginRedirect = array('controller' => 'assessments', 'action' => 'index');

	}

/**
 * login() for UsersController
 * 
 * Standard login() function for cakePHP Auth Component
 * @link http://book.cakephp.org/view/1250/Authentication
 * 
 * Auth is a core component and has been included in app/app_controller.php 
 * The login function does not do anything special and follows the standard cakephp
 * conventions.
 *
 */

	function login(){

	}

/**
 * logout() for UsersController
 * 
 * Standard logout() function for cakePHP Auth Component
 * @link http://book.cakephp.org/view/1250/Authentication
 * 
 * Auth is a core component and has been included in app/app_controller.php 
 * The logout function does not do anything special and follows the standard cakephp
 * conventions.
 *
 */

	function logout() {

		$this->Session->destroy();
		$this->redirect($this->Auth->logout());

	}

/**
 * student_login() for UsersController
 * 
 * The student_login method is an implementation of an openid login
 *
 * Originally designed to manage the login of students via open id (now obsolete)
 * 
 * It remains here as a placeholder and will eventually be used to implement an 
 * openID login for the asessment sessions. The concept is to generate an asessions 
 * token for use in an Assessment Session view implementation which would provider
 * greater security on the Assessment Session.
 *
 * The openid component was developed by Daniel Hofstetter.
 * Depends on version 2.2.2 of the PHP OpenID library (http://openidenabled.com/php-openid/)
 * @link http://code.42dh.com/openid/
 *
 */

	function student_login(){

		$returnTo = 'http://'.$_SERVER['SERVER_NAME'].'/users/student_login';

		if (!empty($this->data)) {

			try {
				$this->Openid->authenticate($this->data['OpenidUrl']['openid'], $returnTo, 'http://'.$_SERVER['SERVER_NAME']);
			}
			catch (InvalidArgumentException $e) {
				$this->Session->setFlash('Invalid OpenID');
			} 
			catch (Exception $e) {
				$this->Session->setFlash($e->getMessage());
			}

		}
		elseif ($this->Openid->isOpenIDResponse()) {

			$response = $this->Openid->getResponse($returnTo);

			if ($response->status == Auth_OpenID_CANCEL) {
				$this->Session->setFlash('Verification cancelled');
			} 
			elseif ($response->status == Auth_OpenID_FAILURE) {
				$this->Session->setFlash('OpenID verification failed: '.$response->message);
			} 
			elseif ($response->status == Auth_OpenID_SUCCESS) {
				$this->Session->setFlash('OpenID Success: '.$response->message);
			}

		}

    }

/**
 * search() for UsersController
 * 
 * The student method finds all users for a list in the view
 * This method is part of the teacher's administration area
 *
 */

	function search(){

		$this->User->unbindModel(
			array('hasMany' => array('Asessionlog'))
		);

		$users = $this->User->find('all');
		$this->set('users',$users);

	}

/**
 * register() for UsersController
 * 
 * Used to register a new teacher / admin user
 *
 */


	function register() {

		if(!empty($this->data) && $this->Captcha->protect('User')) {

			$this->User->create();
			$this->User->saveField('activation_code', '');
			$this->User->saveField('username', '');
			$this->User->saveField('password', '');
			if($this->User->save($this->data)) {
				$this->Session->setFlash('Registration Complete! Please check your email to complete the registration process.');
				$unsalted_password = $this->User->getRandomPassword();
				$this->User->saveField('password', $unsalted_password);
				//$this->User->saveField('active', 1);
				$this->sendActivationEmail($this->User->id, $unsalted_password);
				$this->sendRegoEmail($this->User->id, $unsalted_password);
				$this->redirect('/users/login/');
			}

		}

	}

	function password_recover(){

		if(!empty($this->data) && $this->Captcha->protect('User')) {

			$user_exists = $this->User->find('first', array('conditions' => array('User.email' => $this->data['User']['email'])));

			if (!empty($user_exists)){

				$this->User->id = $user_exists['User']['id'];
				//$this->User->saveField('active', 0);
				$new_password = $this->User->getRandomPassword();
				$this->User->saveField('password', $new_password);
				$this->Session->setFlash('A new password has been generated and sent to your e-mail address. Please wait for an email to confirm your new password is active.');
				$this->sendRegoEmail($user_exists['User']['id'], $new_password);
				//$this->sendActivationEmail($user_exists['User']['id'], $new_password);
				$this->redirect('/users/login/');

			}else{

				$this->Session->setFlash('Could not find the supplied e-mail address. Please check it and try again.');

			}

		}

	}

	function activate($user_id = null, $in_hash = null) {

		$this->User->id = $user_id;
		$user = $this->User->read();
		if ($this->User->exists() && ($in_hash == $user['User']['activation_code'])) {

			$this->User->saveField('activation_code', '');
			$this->User->saveField('active', 1);
			$this->Session->setFlash('Account has been activated.');
			$this->sendActiveEmail($user_id);
			$this->redirect('/assessments');

		} else if ($this->User->exists() && $user['User']['activation_code'] == '') {

			$this->Session->setFlash('This account has already been activated');
			$this->redirect('/assessments');

		} else {

			$this->Session->setFlash('Invalid activation User');
			$this->redirect('/assessments');

		}

	}

	function add(){

		if(!empty($this->data)){

			$unsalted_password = $this->data['User']['password_a'];
			$this->data['User']['password'] = $this->data['User']['password_a'];
			$this->data['User']['active'] = 1;
			$this->data['User']['activation_code'] = '';

			//error_log(print_r($this->data,true));
			$this->User->create();

			if($this->User->save($this->data)) {

				error_log('Added');
				$this->Session->setFlash('User Added!');
				$this->sendRegoEmail($this->User->id, $unsalted_password);
				$this->redirect('/users/search/');
				
			}
			else
			{
				echo "ERROR";
			}

		}

		$this->set('courses', $this->Course->find('list'));
		$this->set('usergroups', $this->Usergroup->find('list'));

	}
	
	function edit($id = false) 
	{

		if(!empty($this->data)) 
		{
			if($this->User->save($this->data)) 
			{
				if (!empty($this->data['User']['password_change'])){
					$this->User->saveField('password', $this->data['User']['password_change']);
					$this->Session->setFlash('User Profile Updated. Password modified successfully.');
					//echo "Change password";
					#error_log('password change exists');
				}else{
					$this->Session->setFlash('User Profile Updated');
					//echo "No Change password";
					#error_log('password change does not exist');
				}
				$this->set('redirect', true);
			}
		}

		$this->data = $this->User->findById($id);

		$this->set('user',$this->data);
		$this->set('courses', $this->Course->find('list'));
		$this->set('usergroups', $this->Usergroup->find('list'));

	}

	function delete($id=null){

		if ($id != null){
			$this->User->delete($id);
			$this->Session->setFlash("User Removed!");
			$this->redirect('/users/search/');
		}

	}

	#################
	# ACTION METHODS
	#################

	function sendActivationEmail($user_id, $password) {

		$user = $this->User->findById($user_id);

		if ($user === false) {
			debug(__METHOD__." failed to retrieve User data for user.id: {$user_id}");
			return false;
		}

		$activation_code = $this->User->getActivationHash();
		$this->User->saveField('activation_code', $activation_code);

		$this->set('activate_url', Configure::read('Settings.base_url'). '/users/activate/' . $user_id . '/' . $activation_code);
		$this->set('username', $user['User']['username']);
		$this->set('password', $password);
		$this->set('firstname', $user['User']['firstname']);
		$this->set('lastname', $user['User']['lastname']);
		//send email to multiple addresses
		$emails = Configure::read('Settings.activation_email');
		$i = 0;
		foreach($emails as $email)
		{
			$this->Email->to = $email;
			
			$this->Email->subject = 'Activate '.Configure::read('Settings.company').' '.Configure::read('Settings.version').' Registration';
			$this->Email->from = Configure::read('Settings.from_email');
			$this->Email->template = 'activate';
			$this->Email->sendAs = 'html';
			
			$this->Email->smtpOptions = array(
				'port'=>'25', 
				'timeout'=>'30',
				'host' => 'localhost',
			);

			$this->Email->delivery = 'smtp';
			$this->Email->send();
		}
		

	}

	function sendRegoEmail($user_id, $password) {

		$user = $this->User->findById($user_id);

		if ($user === false) {
			debug(__METHOD__." failed to retrieve User data for user.id: {$user_id}");
			return false;
		}

		$this->set('username', $user['User']['username']);
		$this->set('password', $password);
		$this->set('firstname', $user['User']['firstname']);
		$this->set('lastname', $user['User']['lastname']);

		$this->Email->to = $user['User']['firstname'].' '.$user['User']['lastname'].' <'.$user['User']['email'].'>';
		$this->Email->subject = Configure::read('Settings.company').' '.Configure::read('Settings.version').' Registration';
		$this->Email->from = Configure::read('Settings.from_email');
		$this->Email->template = 'register';
		$this->Email->sendAs = 'html';
		
		$this->Email->smtpOptions = array(
			'port'=>'25', 
			'timeout'=>'30',
			'host' => 'localhost',
		);

		$this->Email->delivery = 'smtp';
		return $this->Email->send();

	}

	function sendActiveEmail($user_id) {

		$user = $this->User->findById($user_id);

		if ($user === false) {
			debug(__METHOD__." failed to retrieve User data for user.id: {$user_id}");
			return false;
		}

		$this->set('login_url', Configure::read('Settings.base_url'). '/users/login');
		$this->set('firstname', $user['User']['firstname']);
		$this->set('lastname', $user['User']['lastname']);

		$this->Email->to = $user['User']['firstname'].' '.$user['User']['lastname'].' <'.$user['User']['email'].'>';
		$this->Email->subject = Configure::read('Settings.company').' '.Configure::read('Settings.version').' Registration';
		$this->Email->from = Configure::read('Settings.from_email');
		$this->Email->template = 'active';
		$this->Email->sendAs = 'html';
		
		$this->Email->smtpOptions = array(
			'port'=>'25', 
			'timeout'=>'30',
			'host' => 'localhost',
		);

		$this->Email->delivery = 'smtp';
		return $this->Email->send();

	}

	################
	# CALC METHODS
	################

}# END CLASS

?>
